iT邦幫忙

2023 iThome 鐵人賽

DAY 2
0

在本機做好 Docker image 後,接下來要把它推(push)上 AWS ECR repository~

開始前先註冊一個 AWS 帳號唷~還有在 AWS 裡要去各服務的頁面可以在左上角的搜尋框輸入關鍵字:

https://ithelp.ithome.com.tw/upload/images/20230912/20160671ImyM9wwKpy.png

什麼是 ECR?

ECR 的全名是 Elastic Container Registry,是 AWS 提供來放 Docker image 的服務。我們可以在其中建立 public repository,像 Docker Hub 一樣公開存取,也能建立 private repository 在登入後才能存取 image。ECR 也跟 Elastic Container Service(ECS)和 Elastic Kubernetes Service(EKS)整合,ECS 跟 EKS 能簡單的存取 ECR 內的 image。

之後我們 ECS 便是從 ECR 取得網頁 application 的 image 來執行,所以現在要先知道如何把 image push 進 ECR repository。

建立 ECR Repository

要 push image 首先當然要有個存放 image 的 repository,讓我們進到 web console 來開一個吧~

https://ithelp.ithome.com.tw/upload/images/20230912/20160671hsNcWYl7Db.png

點進 Repositories:

https://ithelp.ithome.com.tw/upload/images/20230912/201606716fwk7aHdLr.png

點 Create repository:

https://ithelp.ithome.com.tw/upload/images/20230912/20160671ijPIwYVWF3.png

選擇 private repository 並輸入 repository name,後面設定保持預設點選 Create。

https://ithelp.ithome.com.tw/upload/images/20230912/20160671a7Gdsfp912.png

這樣就建立一個名叫 my-app 的 ECR repository 啦~接著要把 docker image push 進來。

docker login ECR

因為我們使用 private repository,不像 public repository 可以直接使用,要經過 docker login 驗證才能存取 image。

AWS CLI & Credentials

AWS CLI 是 AWS 的 command line 工具,以指令操作各種 AWS 服務。AWS CLI 提供 get-login-password 命令讓我們可以用 docker login 對 ECR 做驗證。(ref)

我們先安裝 AWS CLI,參考 官方文件 即可順利安裝,Linux 的安裝指令如下:

$ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
$ unzip awscliv2.zip
$ sudo ./aws/install
$ aws --version  # 確認是否安裝成功,成功會看到 aws cli 的版本

安裝 AWS CLI 後還要進行設定,它才知道並且能夠操作我們帳號內的各項服務與資源,設定方式參考 官方文件aws configure 輸入 key id 跟 secret 等資訊。

咦?key id 跟 secret 要從哪來?讓我們進到 IAM(Identity and Access Management):

https://ithelp.ithome.com.tw/upload/images/20230912/20160671tMLMleoQAv.png

點 Users 下面的數字進入 Users 後找到要使用的 IAM user。如果你沒有建立 IAM user,可以參考 官方文件 建立一個 IAM user 來使用。一般建議不要以 AWS root account(就是直接用 email 登入的那個帳號)來操作,會新增一個擁有 AdministratorAccess 權限的 IAM user 進行平常的管理操作。進入該 IAM user 的畫面會看到下面有一排 tab:

https://ithelp.ithome.com.tw/upload/images/20230912/20160671Axgs1QHVXo.png

到 Security credentials 的 tab,裡面會有一區 Access Keys:

https://ithelp.ithome.com.tw/upload/images/20230912/201606719CH6EUJhzN.png

只要你 access key 不到 2 把,就可以按右邊的 Create access key 來新增:

https://ithelp.ithome.com.tw/upload/images/20230912/20160671Kd3KbgokQ0.png

它會問你要拿 key 來做什麼、給你其他替代方案的建議,我們這邊先不深入這些選項,勾選底下的 I understand the above recommendation and want to proceed to create an access key 後 Next,下一頁可以選填描述,最後 Create key 會看到:

https://ithelp.ithome.com.tw/upload/images/20230912/20160671awZ9yAcXIf.png

按 Secret access key 的 show 就會顯示 secret,這頁只會顯示一次,所以要配合 aws configure 一起設定好。

簡單介紹一下 IAM(Identity and Access Management),它是 AWS 控管權限的服務,裡面主要有 user、group、role 跟 policy。user 跟一般觀念的使用者一樣,可以登入跟操作。role 跟 user 有點像,簡單區分可以想成 user 是給「人」使用的「帳號」(實際上當然不是只給人用,程式也可以用 user 來打 API),role 則是給「AWS 的 service 或機器」使用的。policy 是權限的定義,定義什麼事可以做、什麼事不能做,一個 user、role 或 group 可以綁(attach)多個 policy、一個 policy 也可以 attach 到多個 user、role 或 group 上。group 如其名是群組,想讓某一群 user 有相同權限,可以建立一個 group 並 attach 相關 policy,再把這些 user 加進這個 group。

AWS 在權限方面採取「沒說可以做(allow)的事情就不能做(deny)」的原則,如果沒有明確在 policy 裡寫可以做某個操作(action),預設就是不能做該操作。實際使用上,我們應該讓 user 或 role 不多不少、剛好擁有需要的權限即可,像是只需要讀取 s3 上的檔案就只給 read-only 而不要給 full access,也不要給其他 service 的權限。

怎麼知道要給哪些權限呢?如果是常用情境,像是 push 跟 pull docker image,可以找找看 AWS 文件有沒有寫或者相關的 example。如果是自己寫的程式、沒有對應的 example 或文件,最簡單的方式就是把你要做的操作執行下去,AWS 通常會告訴你缺哪個 action,一個個補上直到能正常操作完畢。

login ECR 需要的 IAM policy

要用 AWS CLI 跟 docker 登入 ECR,在 AWS 這部份需要以下的 IAM 權限 policy:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "ecr:GetAuthorizationToken",
            "Resource": "*"
        }
    ]
}

怎麼幫 IAM user 加 policy 呢?一樣進到那個 IAM user,在 Permissions 這個 tab 點右邊的 Add permissions,簡(ㄌㄢˇ)單(ㄉㄨㄛˋ) 一點可以直接 Create inline policy。

https://ithelp.ithome.com.tw/upload/images/20230912/201606712ZmvGyCa9r.png

https://ithelp.ithome.com.tw/upload/images/20230912/20160671YXogkKrps9.png

進到選擇要什麼 permission 的畫面後,因為我們已經有 json 了,右上角切換到 JSON 模式:

https://ithelp.ithome.com.tw/upload/images/20230912/20160671XHcVXB4h1k.png

把上面的 policy json 貼進去後 Next:

https://ithelp.ithome.com.tw/upload/images/20230912/20160671lAaIJjk5N0.png

幫 policy 取個名字後 Create policy,完成後便能在 Permissions 看到剛剛新增的 policy:

https://ithelp.ithome.com.tw/upload/images/20230912/20160671EcXzwQySD2.png

login ECR

終於可以 docker login 了!

$ aws ecr get-login-password --region [region] | \
  sudo docker login \
    --username AWS \
    --password-stdin [AWSAccountID].dkr.ecr.[region].amazonaws.com

上面的 [region][AWSAccountID] 要換成你自己的,登入成功會看到 Login Succeed

把 image 推上 ECR repository

總算可以推 image 了吧!不不不……還缺一個小小的步驟,那就是把 push image 到 ECR 需要的 IAM 權限 policy 加到 IAM user 身上 (ref):

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ecr:CompleteLayerUpload",
                "ecr:GetAuthorizationToken",
                "ecr:UploadLayerPart",
                "ecr:InitiateLayerUpload",
                "ecr:BatchCheckLayerAvailability",
                "ecr:PutImage"
            ],
            "Resource": "arn:aws:ecr:[REGION]:[ACCOUNT_ID]:repository/[REPO_NAME]"
        }
    ]
}

這個 policy 是允許(allow)對 resource 指定的 ECR repository 做 action 裡的這些動作。(可以看到 action 分得非常細~)

終於要推 image 了!要推 image 進 ECR repository 要幫它上 tag 然後 push:

$ docker tag [ImageId] [AWSAccountID].dkr.ecr.[region].amazonaws.com/my-app:latest
$ docker push [AWSAccountID].dkr.ecr.[region].amazonaws.com/my-app:latest

push 成功的話,會在 ECR repository 看到像這樣的畫面:

https://ithelp.ithome.com.tw/upload/images/20230912/20160671u92oP48pbX.png

docker tag 就像是幫 image 貼個好認的標籤,讓我們可以用標籤來指定某個 image,不然 image 是以 id 來識別的,應該不太有人能記住那些 id… 🧐

如果 image 只在本機使用,tag 想怎麼取都可以,但如果想要 push 出去(像我們要 push 到 ECR,或者想 push 到 Docker Hub),tag 必須遵照格式:[HOST[:PORT_NUMBER]/]PATH:[TAG] ,就像這裡的 [AWSAccountID].dkr.ecr.[region].amazonaws.com/my-app:latest 。host 與 port 是 registry 服務的 host name 跟 port,path 則是要 push 的 repository 所在位置,各家 registry 會有自己對 path 的定義。最後的 tag 可以不指定,預設會用 latest,通常會用來標示 image 的版本、使用的 base image OS 等等資訊。

docker pull ECR 的 image

既然有 push 也說明從 ECR repository pull image 需要的 IAM policy 以及指令,畢竟我們有可能需要 pull image 下來 debug 之類的。

pull image 需要的 IAM policy 如下:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ecr:BatchGetImage",
                "ecr:GetDownloadUrlForLayer"
            ],
            "Resource": "arn:aws:ecr:[REGION]:[ACCOUNT_ID]:repository/[REPOSITORY]"
        }
    ]
}

把 policy 加到 IAM user 後就能 docker pull ECR 上的 image:

$ docker pull [AWSAccountID].dkr.ecr.[region].amazonaws.com/my-app:latest

上一篇
Day 1 在本機執行 Laravel container
下一篇
Day 3 AWS 的網路:VPC
系列文
AWS ECS + Gitlab + Laravel + Terraform 從入門到摔坑30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言